#ifndef     __COND_VAR_H
#define     __COND_VAR_H

#include "../rtx/rtx_os.h"
#include "../utils/nocopyable.h"

namespace rtos {

class CondVar : private utils::NoCopyable {

public:
    static constexpr uint32_t FLAG_LOCK = 0x01;
    static constexpr uint32_t FLAG_NOTIFY = 0x02;

    CondVar(const char *name = "other") {
        osEventFlagsAttr_t attr;
        attr.name = name;
        attr.attr_bits = 0;
        attr.cb_mem = m_cb_mem;
        attr.cb_size = osRtxEventFlagsCbSize;
        m_id = osEventFlagsNew(&attr);
        reset();
    }

    inline void lock() {
        osEventFlagsWait(m_id, FLAG_LOCK, osFlagsWaitAny, osWaitForever);
    }

    inline void unlock() {
        osEventFlagsSet(m_id, FLAG_LOCK);
    }

    inline bool wait(uint32_t timeout = osWaitForever) {
        return 0x00 == (
            osFlagsError & 
            osEventFlagsWait(m_id, FLAG_NOTIFY, osFlagsWaitAny, timeout)
        );
    }

    inline void notify() {
        osEventFlagsSet(m_id, FLAG_NOTIFY);
    }

    inline void reset() {
        osEventFlagsSet(m_id, FLAG_LOCK);
        osEventFlagsClear(m_id, FLAG_NOTIFY);
    }

private:
    osEventFlagsId_t m_id;
    uint64_t m_cb_mem[ (osRtxEventFlagsCbSize + 7) / 8 ];
};

}



#endif
